package com.buaa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.buaa.common.Result;
import com.buaa.dto.LocationDTO;
import com.buaa.dto.UserExtensionDTO;
import com.buaa.entity.User;
import com.buaa.entity.UserExtension;
import com.buaa.entity.UserExtensionActivity;
import com.buaa.enums.OperationType;
import com.buaa.enums.ResponseCode;
import com.buaa.exception.ServiceException;
import com.buaa.mapper.UserExtensionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserExtensionServiceImpl extends ServiceImpl<UserExtensionMapper, UserExtension> implements IService <UserExtension> {


    @Autowired
    private UserExtensionActivityServiceImpl userExtensionActivityServiceImpl;

    @Autowired
    private UserActivityServiceImpl userActivityServiceImpl;

    @Autowired
    private UserExtensionMapper userExtensionMapper;


    @Autowired
    private UserServiceImpl userServiceImpl;

    public List<LocationDTO>  listUserByJob(){
        List<LocationDTO> locationDTOS = null;
        try {
            // 复用 LocationDTO ， 年龄，用户数
            locationDTOS = userExtensionMapper.listUserByJob();
        } catch (ServiceException e) {
            new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(), ResponseCode.DB_EXEC_ERROR.getDesc());
        }
        return locationDTOS;
    }

    public List<LocationDTO>  listUserAttributesByAge(){
        List<LocationDTO> locationDTOS = null;
        try {
            // 复用 LocationDTO ， 年龄，用户数
            locationDTOS = userExtensionMapper.listUserAttributesByAge();
        } catch (ServiceException e) {
            new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(), ResponseCode.DB_EXEC_ERROR.getDesc());
        }
        return locationDTOS;
    }
    public List<LocationDTO>  listUserAttributesByLocation(){
        List<LocationDTO> locationDTOS = null;
        try {
            locationDTOS = userExtensionMapper.listUserAttributesByLocation();
        } catch (ServiceException e) {
            new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(), ResponseCode.DB_EXEC_ERROR.getDesc());
        }
        return locationDTOS;
    }

    public List<UserExtension> getUserExtList(List<User> userList) {

        if (ObjectUtil.isNull(userList) || (ObjectUtil.isEmpty(userList) && userList.size() == 0))
            return null;
        else {
            List<Integer> ids = new ArrayList<>();
            for (User user : userList) {
                Integer id = user.getId();
                ids.add(id);
            }

            List<UserExtension> userExtensionList = null;
            try {
                userExtensionList = listByIds(ids);
            } catch (ServiceException e) {
                new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(), ResponseCode.DB_EXEC_ERROR.getDesc());
            }
            return userExtensionList;
        }
    }

    public Result deletUserExtByIds(List<Integer> ids, HttpServletRequest request) {

        if (null == ids || (null != ids && ids.size() == 0))
            return Result.error(ResponseCode.DEL_USER_EXT_BULK_INFO.getKey(), ResponseCode.DEL_USER_EXT_BULK_INFO.getDesc());

        User currentOpUser = userServiceImpl.getOperateUser(request); // 获取当前操作人

        // 批量删除前先保持
        for (Integer key :ids) {
            UserExtension userExtension = getById(key);
            UserExtensionActivity userActivity = new UserExtensionActivity();
            BeanUtil.copyProperties(userExtension, userActivity, true);
            userActivity.setUserExtId(userExtension.getId());
            Integer id = null;
            userActivity.setId(id);
            userActivity.setOperationType(OperationType.USER_DELETE_BULK.getDesc());
            userActivity.setReviser(currentOpUser.getUserName());
            userActivity.setRevisionTime(LocalDateTime.now());
            try {
                userExtensionActivityServiceImpl.save(userActivity); // 不中断业务
            } catch (ServiceException e){
                e.printStackTrace(); //
            }
        }

        boolean r = false;
        try {
            r = removeByIds(ids);
        }catch (ServiceException e){
            new ServiceException(ResponseCode.DEL_USER_EXT_BULK_FAILURE.getKey(), ResponseCode.DEL_USER_EXT_BULK_FAILURE.getDesc());
        }
        if (r)
            return  Result.success(ResponseCode.DEL_USER_EXT_BULK_SECCESS.getKey(), ResponseCode.DEL_USER_EXT_BULK_SECCESS.getDesc(),"");
        else
            return  Result.error(ResponseCode.DEL_USER_EXT_BULK_FAILURE.getKey(), ResponseCode.DEL_USER_EXT_BULK_FAILURE.getDesc());

    }

    public Result deleteUserExtById(Integer id, HttpServletRequest request) {
        // 根据ID删除账号，返回操作结果
        // 删除前先记录log
        UserExtension userExtension = null;
        boolean r = false;

        if (ObjectUtils.isNull(id))
            return Result.success(ResponseCode.DEL_USER_EXT_INFO.getKey(), ResponseCode.DEL_USER_EXT_INFO.getDesc(),"");
        else {
            userExtension = getById(id);
        }
        if (ObjectUtils.isNull(userExtension))
            return Result.success(ResponseCode.DEL_USER_EXT_INFO.getKey(), ResponseCode.DEL_USER_EXT_INFO.getDesc(),"");
        else {
            // 先执行删除，
            try{
                r = removeById(id);
            }catch (ServiceException e){
                new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(), ResponseCode.DB_EXEC_ERROR.getDesc());
            }
            if (r) { // 因为事先已经备份数据，删除成功后，写入历史表
                User currentOpUser = userServiceImpl.getOperateUser(request);
                UserExtensionActivity userExtensionActivity = new UserExtensionActivity();
                BeanUtil.copyProperties(userExtension, userExtensionActivity, true);
                userExtensionActivity.setUserExtId(userExtension.getId());
                Integer eid = null;
                userExtensionActivity.setId(eid);
                userExtensionActivity.setOperationType(OperationType.USER_EXT_DELETE.getDesc());
                userExtensionActivity.setReviser(currentOpUser.getUserName());
                userExtensionActivity.setRevisionTime(LocalDateTime.now());
                try {
                    userExtensionActivityServiceImpl.save(userExtensionActivity); // 记录log ， 无需终止应用
                } catch (ServiceException e) {
                    e.printStackTrace();
                }
            }
        }

        if (r)
            return  Result.success(ResponseCode.DEL_USER_EXT_SECCESS.getKey(), ResponseCode.DEL_USER_EXT_SECCESS.getDesc(),"");
        else
            return  Result.error(ResponseCode.DEL_USER_EXT_FAILURE.getKey(), ResponseCode.DEL_USER_EXT_FAILURE.getDesc());

    }


    public Result saveUserExt(@RequestBody UserExtensionDTO userExtensionDTO, HttpServletRequest request){

        // 判断是否为空
        if (ObjectUtils.isNull(userExtensionDTO))
            return Result.error(ResponseCode.SC_NO_CONTENT.getKey(), ResponseCode.SC_NO_CONTENT.getDesc());

        User user = userServiceImpl.getOperateUser(request);

        boolean result = false;
        // ID为空，说明是第一次insert 或者删除之后再次insert
        if (ObjectUtils.isNull(userExtensionDTO.getId())){
            // insert 到主表
            UserExtension userExtension = new UserExtension();
            BeanUtil.copyProperties(userExtensionDTO, userExtension, true);
            LocalDateTime openDate = LocalDateTime.now();
            userExtension.setCreateTime(openDate);  //  DB 有配置，但是不自动 insert，后续需要查看
            userExtension.setCreateBy(user.getUserName());
            // 因为是更新，所以 insert 时 同步写 更新时间
            userExtension.setRevisionTime(openDate);
            userExtension.setReviser(user.getUserName());
            // 涉及主表事物，需要 try -catch 抛出异常
            try {
                result = saveOrUpdate(userExtension);
            }catch (ServiceException e){
                new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(),ResponseCode.DB_EXEC_ERROR.getDesc());
            }

            if (result) { // 创建成功后 ，才 insert 到 log 表
                //同时insert 到 日志表
                UserExtensionActivity userExtensionActivity = new UserExtensionActivity();
                BeanUtil.copyProperties(userExtension, userExtensionActivity, true);
                Integer id = null;
                userExtensionActivity.setId(id);//设置为空，便于 insert
                userExtensionActivity.setOperationType(OperationType.USER_EXT_INSERT.getDesc());

                // 基于 user_id 去 user_extension 表查询 id , 作为 ext_activity.user_ext_id
                UserExtension u =   getUserExtByUserId(userExtension.getUserId());
                userExtensionActivity.setUserExtId(u.getId());
                userExtensionActivity.setRevisionTime(openDate);
                userExtensionActivity.setReviser(user.getUserName());
                // 涉及 log 表操作，需要 try -catch ，但是不抛出异常
                try {
                    userExtensionActivityServiceImpl.saveOrUpdate(userExtensionActivity);
                } catch (ServiceException e) {
                    e.printStackTrace();
                }
            }
            if (result){
                return Result.success(ResponseCode.INSERT_USER_EXT_SECCESS.getKey(), ResponseCode.INSERT_USER_EXT_SECCESS.getDesc(),"");
            }else {
                return Result.error(ResponseCode.INSERT_USER_EXT_FAILURE.getKey(), ResponseCode.INSERT_USER_EXT_FAILURE.getDesc());
            }

        }else {
            // 说明是 update 操作
            LocalDateTime openDate = LocalDateTime.now();
            UserExtension userExtension = new UserExtension();
            BeanUtil.copyProperties(userExtensionDTO, userExtension, true);
            userExtension.setRevisionTime(openDate);
            userExtension.setReviser(user.getUserName());
            // 涉及主表事物，需要 try -catch 抛出异常
            try {
                result = saveOrUpdate(userExtension);
            }catch (ServiceException e){
                new ServiceException(ResponseCode.DB_EXEC_ERROR.getKey(),ResponseCode.DB_EXEC_ERROR.getDesc());
            }
            //同时insert 到 日志表
            if (result) { // 更新成功后 ，才 insert 到 log 表
                //同时insert 到 日志表
                UserExtensionActivity userExtensionActivity = new UserExtensionActivity();
                BeanUtil.copyProperties(userExtension, userExtensionActivity, true);
                userExtensionActivity.setOperationType(OperationType.USER_EXT_UPDATE.getDesc());
                Integer id = null;
                userExtensionActivity.setId(id);//设置为空，便于 insert
                userExtensionActivity.setUserExtId(userExtension.getId());
                // 涉及 log 表操作，需要 try -catch ，但是不抛出异常
                try {
                    userExtensionActivityServiceImpl.saveOrUpdate(userExtensionActivity);
                } catch (ServiceException e) {
                    e.printStackTrace();
                }
            }
            if (result){
                return Result.success(ResponseCode.UPDATE_USER_EXT_SECCESS.getKey(), ResponseCode.UPDATE_USER_EXT_SECCESS.getDesc(),"");
            }else {
                return Result.error(ResponseCode.UPDATE_USER_EXT_FAILURE.getKey(), ResponseCode.UPDATE_USER_EXT_FAILURE.getDesc());
            }
        }

     }


    public UserExtension getUserExtByUserId(Integer userId){
        // 创建查询条件，指定查询警察身份证号为policeId的用户
        QueryWrapper wrapper = new QueryWrapper<UserExtension>().eq("user_id", userId);
        wrapper.last("LIMIT 1"); // 如果是多个会抛出异常，随机取一条加上限制条件
        return getOne(wrapper);
    }
    public boolean checkUserId(Integer userId){
        // 创建查询条件，指定查询警察身份证号为policeId的用户
        Wrapper wrapper = new QueryWrapper<User>().eq("user_id", userId);
        // 查询符合查询条件的用户数量
        long count = this.count(wrapper);
        // 如果查询结果数量大于0，说明身份证号存在，返回true；否则返回false
        return count > 0 ? true : false;
    }

    public Map<String,Object> findPageByPidAndUserName(String policeId, String userName,Integer pageNum, Integer pageSize){
        if (StrUtil.isBlank(userName) && StrUtil.isBlank(policeId))
            return findPageByDefault(pageNum, pageSize);
        if (StrUtil.isBlank(userName) && !StrUtil.isBlank(policeId)) {
            //policeId = "%" + policeId +"%"; // mybatis 中 "@select "不支持 %% 这种匹配
            return findPageByPoliceId(policeId, pageNum, pageSize);
        }
        if (!StrUtil.isBlank(userName) && StrUtil.isBlank(policeId)) {
//            userName = "%" + userName +"%"; // mybatis 中 "@select "不支持 %% 这种匹配
            return findPageByUserName(userName, pageNum, pageSize);
        }
        Map<String, Object> res = new HashMap<>();
        if (!StrUtil.isBlank(policeId) && !StrUtil.isBlank(userName)) {
            int total = userExtensionMapper.getTotal();
            pageNum = (pageNum - 1) * pageSize;
//            userName = "%" + userName +"%"; // mybatis 中 "@select "不支持 %% 这种匹配
//            policeId = "%" + policeId +"%"; // mybatis 中 "@select "不支持 %% 这种匹配
            List<UserExtensionDTO> userextList = userExtensionMapper.getUserList(policeId, userName, pageNum, pageSize);
            res.put("pagedata", userextList);
            res.put("total", total);
        } else {
            new ServiceException(ResponseCode.QRY_FAILURE.getKey(), ResponseCode.QRY_FAILURE.getDesc());
        }
        return res;
    }
    public Map<String,Object> findPageByDefault(Integer pageNum, Integer pageSize){
        int total = userExtensionMapper.getTotal();
        int limit = (pageNum - 1) * pageSize;
        System.out.println("limit = " + limit);
        List<UserExtensionDTO> userextList = userExtensionMapper.getUserListByDefault(limit, pageSize);
        Map<String,Object> res=new HashMap<>();
        res.put("pagedata",userextList);
        res.put("total",total);
        return res;
    }

    public Map<String,Object> findPageByPoliceId(String policeId, Integer pageNum, Integer pageSize){
        int total = 0;
        pageNum = (pageNum - 1) * pageSize;
        if (StrUtil.isBlank(policeId)) {
            total = userExtensionMapper.getTotal();
        }
        else {
            total = userExtensionMapper.getTotalWithPoliceId(policeId);
        }

        List<UserExtensionDTO> userextList = userExtensionMapper.getUserListByPid(policeId, pageNum, pageSize);
        Map<String,Object> res=new HashMap<>();
        res.put("pagedata",userextList);
        res.put("total",total);
        return res;
    }

    public Map<String,Object> findPageByUserName(String userName, Integer pageNum, Integer pageSize){
        int total = 0;
        pageNum = (pageNum - 1) * pageSize;
        if (StrUtil.isBlank(userName)) {
            total = userExtensionMapper.getTotal();
        }
        else {
            total = userExtensionMapper.getTotalWithUserName(userName);
        }
        List<UserExtensionDTO> userextList = userExtensionMapper.getUserListByUserName(userName, pageNum, pageSize);
        Map<String,Object> res=new HashMap<>();
        res.put("pagedata",userextList);
        res.put("total",total);
        return res;
    }


}


